/*
 * H264FilePlayer.cpp
 *
 *  Created: 2012-05-29
 *   Author: terry
 */

#include "stdafx.h"
#include "H264FilePlayer.h"
#include "PathUtil.h"

#define     DEFAULT_FRAME_RATE     25.0


H264FilePlayer::H264FilePlayer(const char* filename):
    m_filename(filename),
    m_reader(),
    m_paused(false),
    m_scale(1.0),
    m_frameCount(0),
    m_event(),
    m_cs()
{

}

H264FilePlayer::~H264FilePlayer()
{

}

bool H264FilePlayer::setFileName(const char* filename)
{
    if (!PathUtil::isFile(filename))
    {
        return false;
    }

    m_filename = filename;
    return true;
}

bool H264FilePlayer::open()
{
    if (!m_reader.open(m_filename.c_str()))
    {
        return false;
    }

    bool ret = m_decode.open();
    return ret;
}

void H264FilePlayer::close()
{
    m_decode.close();

    m_reader.close();
}

bool H264FilePlayer::play()
{
    if (isRunning())
    {
        m_paused = false;
        m_event.post();
        return true;
    }

    bool ret = start();

    return ret;
}

bool H264FilePlayer::pause(bool toPause)
{
    if (!isRunning())
    {
        return false;
    }

    m_paused = toPause;

    m_event.post();

    return true;
}

void H264FilePlayer::stopStream()
{
    stop();

    comn::AutoCritSec lock(m_cs);
    m_reader.setPos(0);

    m_paused = false;
    m_scale = 1.0;
    m_frameCount = 0;

}

double H264FilePlayer::getPos()
{
    long fileSize = m_reader.getTotal();
    if (fileSize <= 0)
    {
        return 0;
    }

    double pos = m_reader.getPos();
    pos = pos / fileSize;

    return pos;
}

bool H264FilePlayer::setPos(double pos)
{
    long fileSize = m_reader.getTotal();
    if (fileSize <= 0)
    {
        return false;
    }

    double filePos = pos * fileSize;

    comn::AutoCritSec lock(m_cs);
    return m_reader.setPos((long)filePos);
}

double H264FilePlayer::getDuration()
{
    return m_reader.getTotal();
}

bool H264FilePlayer::setScale(double scale)
{
    if (scale <= 0)
    {
        return false;
    }

    m_scale = scale;
    return true;
}

int H264FilePlayer::run()
{
    while (!m_canExit)
    {
        if (m_paused)
        {
            m_event.wait();
            continue;
        }

        double duration = 1000; // 1 second
        if (dealFrame())
        {
            duration = 1000.0 / DEFAULT_FRAME_RATE;
            duration = duration / m_scale;
        }
        else
        {
            refresh();

            postFileEndMsg();
        }

        m_event.timedwait((int)duration);

    }
    return 0;
}

bool H264FilePlayer::startup()
{
    return true;
}

void H264FilePlayer::cleanup()
{
    // pass
}

void H264FilePlayer::doStop()
{
    m_event.post();
}

bool H264FilePlayer::dealFrame()
{
    comn::AutoCritSec lock(m_cs);

    H264FileReader::H264NaluPacket nalu;
    if (!m_reader.read(nalu))
    {
        return false;
    }

    m_decode.inputData(nalu.data, nalu.length);
    return true;
}